const crypto = require("crypto");
const moment = require('moment');
const jwt = require('jsonwebtoken');
const authConst = require('../constant/auth-const');

module.exports = {
    formatDate: date => new Date(date).toLocaleString(),

    relativeTime: time => moment(new Date(time * 1000)).fromNow(),

    getLatestLoginTime(datetime) {
        if (datetime) {
            const loginDateTime = new Date(datetime);
            const loginYear = loginDateTime.getFullYear();
            const loginMonth = loginDateTime.getMonth() + 1;
            const loginDate = loginDateTime.getDate();
            const loginHours = loginDateTime.getHours();
            const loginMinutes = loginDateTime.getMinutes();

            const currentDateTime = new Date();
            const currentYear = currentDateTime.getFullYear();
            const currentMonth = currentDateTime.getMonth() + 1;
            const currentDate = currentDateTime.getDate();
            const currentHours = currentDateTime.getHours();
            const currentMinutes = currentDateTime.getMinutes();

            if (loginYear < currentYear) {
                return (currentYear - loginYear) + '年前';
            } else if (loginMonth < currentMonth) {
                return (currentMonth - loginMonth) + '个月前';
            } else if (loginDate < currentDate) {
                return (currentDate - loginDate) + '天前';
            } else if (loginHours < currentHours) {
                return (currentHours - loginHours) + '小时前';
            } else if (loginMinutes < currentMinutes) {
                return (currentMinutes - loginMinutes) + '分钟前';
            } else {
                return '刚刚';
            }
        } else {
            return null;
        }
    },

    generateRandomAlphaNum(length) {
        let charSet = '0123456789';
        let randomString = '';
        for (let i = 0; i < length; i++) {
            let randomPoz = Math.floor(Math.random() * charSet.length);
            randomString += charSet.substring(randomPoz, randomPoz + 1);
        }
        return randomString;
    },

    encrypt(password) {
        const md5 = crypto.createHash('md5');
        return md5.update(password).digest('hex');
    },

    jwtSign(userData) {
        return jwt.sign(userData, authConst.jwtConfig.secret);
    },

    jwtSignExpire(userData, expire) {
        return jwt.sign(userData, authConst.jwtConfig.secret, {expiresIn: expire || authConst.jwtConfig.expire});
    },

    jwtVerify(token) {
        return jwt.verify(token, authConst.jwtConfig.secret);
    },

    async sqlQuery(query, params = []) {
        const { app } = this;
        const { SELECT } = app.model.QueryTypes;
        return await app.model.query(query, {replacements: params, type: SELECT});
    },

    async sqlQueryCount(query, params = [], limit = 8, offset = 0) {
        const { app } = this;
        const { SELECT } = app.model.QueryTypes;

        const startIndex = query.indexOf('from');
        const subString = query.substring(startIndex, query.length);
        const queryCount = `select count(*) as count ${subString}`;
        const [countResult] = await app.model.query(queryCount, {replacements: params, type: SELECT});

        const queryString = `${query} limit ${limit} offset ${offset}`;
        const dataResult = await app.model.query(queryString, {replacements: params, type: SELECT});

        return {
            ...countResult,
            rows: dataResult
        }
    },

    async checkApiAuthForRole(roleId, module, func) {
        const queryData =
            `select aa.id, aa.title, aa.type, aa.path, aa.func
                from tbl_role_authority ra
                left join tbl_api_authority aa
                on ra.auth_id = aa.id
                where true
                and ra.role_id = ?
                and ra.type = ?
                and aa.path = ?
                and aa.func = ?`;

        const paramData = [roleId, authConst.authType.apiAuth.value, module, func];
        return await this.sqlQuery(queryData, paramData);
        // return result.some(({path, func}) => (authApi === path + func));
    },

    async setRedisStr(key, val, expire) {
        const { app } = this;
        await app.redis.set(key, val);
        if (expire) {
            await app.redis.expire(key, expire);
        }
    },

    async getRedisStr(key) {
        const { app } = this;
        return await app.redis.get(key);
    },

    async delRedisStr(key) {
        const { app } = this;
        return await app.redis.del(key);
    }
};
